import {ComponentFactoryResolver, ComponentRef, Directive, HostListener, ElementRef, Injector, Input, OnDestroy, OnInit, Renderer2, TemplateRef, ViewContainerRef, EventEmitter, Output} from "@angular/core";
import {AppComponent} from "../../../app.component";
import {PopoverComponent} from "./popover.component";
import {fromEvent} from "rxjs";
import {AppService} from "../../../app.service";
import {GlobalEvent} from "../../../support/event.definition";

export abstract class Options {
  template: any
  // 取值环境
  context?: any = {};
  // 显示方向
  direction?
  // 自动关闭
  autoClose?
  // 双击触法显示
  dblclick?: TemplateRef<any>
  // 初始化事件
  init?: Function
  // 显示事件
  onShow?: Function
  // 隐藏事件
  onHide?: Function
}

@Directive({
  selector: "[ss-platform-popover]"
})
export class PopoverDirective implements OnInit, OnDestroy {

  @Input("ss-platform-popover")
  options: Options
  private element: HTMLElement;
  private componentRef: ComponentRef<any>;
  private subscription: any;
  private unsubscribe: any;

  @Output()
  onShow: EventEmitter<any> = new EventEmitter<any>();
  @Output()
  onHide: EventEmitter<any> = new EventEmitter<any>();

  constructor(
    private elementRef: ElementRef,
    private viewContainer: ViewContainerRef,
    private resolver: ComponentFactoryResolver,
    private appComponent: AppComponent, private $app: AppService) {
    this.subscription = fromEvent(window, "click").subscribe(($event) => {
      let targetElement = $event.target as HTMLElement;
      if (targetElement != this.element && targetElement.parentElement != this.element) {
        this.hidePopover();
      }
    });
    this.unsubscribe = $app.subscribe(GlobalEvent.HidePopover, () => {
      this.hidePopover();
    });
    this.element = this.elementRef.nativeElement;
  }

  ngOnInit(): void {
    if (this.options.template instanceof TemplateRef) {
      this.options.template = {click: this.options.template};
    }
  }

  showPopover() {
    this.element.classList.add("show-popover");
    this.componentRef = this.appComponent.loadComponent(PopoverComponent);
    this.componentRef.instance.options = this.options;
    this.componentRef.instance.sourceElement = this.element;
    this.options.onShow && this.options.onShow(this.options);
  }

  hidePopover() {
    this.element.classList.remove("show-popover");
    if (this.componentRef) {
      this.componentRef.destroy();
    }
    this.options.onHide && this.options.onHide(this.options);
  }

  isDisplay(): boolean {
    return this.element.classList.contains("show-popover");
  }

  toggle(): void {
    if (!this.isDisplay()) {
      this.showPopover();
    } else {
      this.hidePopover();
    }
  }

  // 设置
  private count = 0;
  private _lastClickTimer = 0;

  @HostListener("click", ["$event"])
  click($event): void {
    // 单一 pop
    if (!this.options.template.dblclick) {
      this.options.template.ref = this.options.template.click;
      this.toggle();
    }
    // 单击+双击 pop
    else {
      this.count++;
      // 双击、单击
      this.options.template.ref = this.count == 2 ? this.options.template.dblclick : this.options.template.click
      this.hidePopover();
      this.showPopover();
      clearTimeout(this._lastClickTimer);
      this._lastClickTimer = setTimeout(() => {
        this.count = 0;
      }, 300);
    }
  }

  ngOnDestroy() {
    if (this.componentRef) {
      this.componentRef.destroy();
    }
    this.subscription.unsubscribe();
    this.unsubscribe();
  }

}
